---
title: Kubernetes Deployment Guide
description: Deploy Kaneo on Kubernetes using Helm charts. Complete guide for production-ready deployment with PostgreSQL, ingress configuration, and scaling options.
---
import { Step, Steps } from 'fumadocs-ui/components/steps';

# Kubernetes Deployment Guide

This comprehensive guide explains how to deploy Kaneo on Kubernetes using our official Helm chart. This setup is ideal for production environments where you need scalability, high availability, and enterprise-grade infrastructure.

## Prerequisites

Before you begin, ensure you have:

- **Kubernetes cluster** (v1.19 or higher)
- **Helm 3** installed and configured
- **kubectl** configured to communicate with your cluster
- **Basic knowledge** of Kubernetes and Helm concepts
- **Ingress controller** (nginx, traefik, etc.) for production deployments

## Quick Installation

<Steps>
<Step>
**Clone the Kaneo repository**

```bash
git clone https://github.com/usekaneo/kaneo.git
cd kaneo
```
</Step>

<Step>
**Install with default configuration**

```bash
helm install kaneo ./charts/kaneo --namespace kaneo --create-namespace
```

This will deploy Kaneo with PostgreSQL and default settings.
</Step>

<Step>
**Access your deployment**

Use port forwarding to access the services locally:

```bash
# Port forward to access both services
kubectl port-forward svc/kaneo-web 5173:5173 -n kaneo &
kubectl port-forward svc/kaneo-api 1337:1337 -n kaneo &

# Access the application at http://localhost:5173
```
</Step>
</Steps>

## Production Deployment with Ingress

For production environments, you should expose Kaneo through an Ingress controller:

<Steps>
<Step>
**Create a production values file**

Create a file named `kaneo-values.yaml` with production-ready configuration:

```yaml
# PostgreSQL configuration
postgresql:
  auth:
    password: "your-secure-db-password"
  persistence:
    size: 20Gi
    storageClass: "managed-premium"
  resources:
    limits:
      cpu: 500m
      memory: 512Mi
    requests:
      cpu: 100m
      memory: 128Mi

# API configuration
api:
  env:
    jwtAccess: "your-secure-jwt-token"

  # For production, consider setting resource limits
  resources:
    limits:
      cpu: 500m
      memory: 512Mi
    requests:
      cpu: 100m
      memory: 256Mi

# Web configuration
web:
  env:
    apiUrl: "https://your-domain.com"

  resources:
    limits:
      cpu: 300m
      memory: 256Mi
    requests:
      cpu: 100m
      memory: 128Mi

ingress:
  enabled: true
  className: "nginx"
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/rewrite-target: /$1
  hosts:
    - host: your-domain.com
      paths:
        - path: /?(.*)
          pathType: Prefix
          service: web
          port: 80
        - path: /api/?(.*)
          pathType: Prefix
          service: api
          port: 1337
  tls:
    - secretName: kaneo-tls
      hosts:
        - your-domain.com
```
</Step>

<Step>
**Deploy with custom configuration**

```bash
helm install kaneo ./charts/kaneo \
  --namespace kaneo \
  --create-namespace \
  -f kaneo-values.yaml
```
</Step>

<Step>
**Configure DNS**

Configure your DNS settings to point `your-domain.com` to your Ingress controller's external IP or load balancer.
</Step>

<Step>
**Verify deployment**

You should now be able to access Kaneo at `https://your-domain.com` and the API will be accessible at `https://your-domain.com/api`. 🎉
</Step>
</Steps>

## Using Secrets for Sensitive Data

For better security, you can store sensitive data like JWT tokens and database credentials in Kubernetes Secrets:

<Steps>
<Step>
**Create secrets**

```bash
kubectl create secret generic kaneo-secrets \
  --namespace kaneo \
  --from-literal=jwt-access="your-secure-jwt-token" \
  --from-literal=postgres-password="your-secure-db-password"
```
</Step>

<Step>
**Update values to use secrets**

```yaml
postgresql:
  auth:
    existingSecret: "kaneo-secrets"
    secretKeys:
      userPasswordKey: "postgres-password"

api:
  env:
    existingSecret:
      enabled: true
      name: "kaneo-secrets"
      key: "jwt-access"
```
</Step>

<Step>
**Upgrade your deployment**

```bash
helm upgrade kaneo ./charts/kaneo \
  --namespace kaneo \
  -f kaneo-values.yaml
```
</Step>
</Steps>

## Using External PostgreSQL Database

If you prefer to use an external PostgreSQL database instead of the bundled one:

<Steps>
<Step>
**Configure external database**

Update your values file to disable the bundled PostgreSQL and configure external database:

```yaml
# Disable bundled PostgreSQL
postgresql:
  enabled: false

api:
  env:
    jwtAccess: "your-secure-jwt-token"
    database:
      external:
        enabled: true
        host: "your-postgres-host.com"
        port: 5432
        database: "kaneo"
        username: "kaneo_user"
        password: "your-db-password"
```
</Step>

<Step>
**Deploy or upgrade**

```bash
helm upgrade --install kaneo ./charts/kaneo \
  --namespace kaneo \
  --create-namespace \
  -f kaneo-values.yaml
```
</Step>
</Steps>

## Using Gateway API

As an alternative to Ingress, you can use the Kubernetes Gateway API for more advanced routing capabilities:

<Steps>
<Step>
**Verify Gateway API installation**

Make sure the Gateway API is installed in your cluster.
</Step>

<Step>
**Create Gateway configuration**

Create a file named `kaneo-gateway.yaml`:

```yaml
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
  name: kaneo
  namespace: kaneo
spec:
  parentRefs:
  - name: main-gateway  # Your gateway name
    namespace: gateway-system  # Your gateway namespace
    sectionName: https
  hostnames:
  - "your-domain.com"
  rules:
  # Frontend route (root path)
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: kaneo-web
      port: 80
  # API route (api path prefix)
  - matches:
    - path:
        type: PathPrefix
        value: /api
    backendRefs:
    - name: kaneo-api
      port: 1337
    filters:
    - type: URLRewrite
      urlRewrite:
        path:
          type: ReplacePrefixMatch
          replacePrefixMatch: /
```
</Step>

<Step>
**Apply the configuration**

```bash
kubectl apply -f kaneo-gateway.yaml
```
</Step>
</Steps>

## Database Management

### Backup and Recovery

For production deployments, consider implementing regular database backups:

```bash
# Example backup command
kubectl exec -it deployment/kaneo-postgresql -- pg_dump -U kaneo_user kaneo > kaneo-backup.sql
```

### Migration from SQLite

If you're migrating from a previous SQLite-based installation, you'll need to:
1. Export your data from SQLite
2. Deploy the new PostgreSQL-based chart
3. Import your data into PostgreSQL

Contact the Kaneo community on [Discord](https://discord.gg/rU4tSyhXXU) for migration assistance.

## Uninstalling

To uninstall Kaneo from your Kubernetes cluster:

```bash
helm uninstall kaneo -n kaneo
```

This will remove all the Kubernetes components associated with the chart and delete the release.

## Next Steps

- Configure monitoring with Prometheus and Grafana
- Set up automated backups for your PostgreSQL database
- Implement horizontal pod autoscaling for high availability